﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using Mogre;
using MogreNewt;


namespace WastedMechanics
{
    class HUDController
    {                         
        public GuiFrame FocusFrame;
        public GuiTextLabel FocusLabel;

        public GuiFrame MessageFrame;
        GuiList MessageList;

        public GuiFrame LifeBarsFrame;
        GuiControl LifeBarPlayerBg;
        GuiControl LifeBarPlayer;
        GuiControl LifeBarNPCBg;
        GuiControl LifeBarNPC;
        public GuiControl Crosshair;
        float LifeBarWidth = 0.2f;

        public GuiFrame RepliesFrame;
        public GuiList RepliesList;
        public GuiFrame SubtitlesFrame;
        public GuiTextLabel SubtitlesLabel;

        public GuiFrame InventoryFrame;
        public GuiList InventoryList;
        public GuiTextLabel InventoryDescription;
        public GuiTextLabel InventoryStats;
        public GuiControl InventoryWeaponPistol;
        public GuiControl InventoryWeaponM1H;
        public GuiControl InventoryArmour;

        public GuiFrame PlunderFrame;
        public GuiList PlunderList;

        public GuiFrame BarterFrame;
        public GuiList BarterPlayerEquip;
        public GuiList BarterPlayerOffer;
        public GuiList BarterNPCEquip;
        public GuiList BarterNPCOffer;
        public GuiTextLabel BarterDescription;
        public GuiTextLabel BarterStats;
        public GuiButton BarterAcceptBtn;

        public GuiFrame GameEndFrame;     

        class EquipmentItem
        {
            public Item Item;
            public Equipment Equipment;
            public EquipmentItem(Item item, Equipment equipment)
            {
                Item = item;
                Equipment = equipment;
            }
        }

        class ScreenMessage
        {
            public GuiControl Control;
            public float LifeTime;

            public ScreenMessage(GuiControl control, float lifeTime)
            {
                Control = control;
                LifeTime = lifeTime;
            }

            public void Update()
            {
                LifeTime -= Engine.FixedTimeStep;
            }

            public bool IsOutDated
            {
                get { return LifeTime <= 0; }
            }
        }
        List<ScreenMessage> ScreenMessages;

        Character Character
        {
            get
            {
                return Engine.HumanController.Character;
            }
        }

        IContainer ExchangeObject
        {
            get
            {
                return Engine.HumanController.ExchangeObject;
            }
        }

        SelectableObject FocusObject
        {
            get
            {
                return Engine.HumanController.FocusObject;
            }
        }

        public HUDController()
        {
            FocusFrame = Engine.GuiManager.NewLayer("FocusFrame");
            FocusFrame.ZOrder = 1;
            FocusFrame.IsZOrderFixed = true;
            FocusFrame.SetControl(new GuiTextLabel("FocusLabel"));
            FocusLabel = FocusFrame.Control as GuiTextLabel;
            FocusLabel.FontName = "Ubuntu";
            FocusLabel.CharHeight = 0.04f;
            FocusLabel.ColourTop = new ColourValue(0.3f, 0.1f, 0);
            FocusLabel.ColourBottom = new ColourValue(1, 1.0f, 0.6f);
            FocusLabel.Alignment = TextAreaOverlayElement.Alignment.Center;

            CreateLifeBarsFrame();

            CreateMessageFrame();

            CreateTalkFrame();

            CreateInventoryFrame();

            CreatePlunderFrame();

            CreateBarterFrame();

            CreateGameEndFrame();

            Engine.GuiManager.OnScreenDropAccept += (what =>
                what.UserData is EquipmentItem
                && (what.UserData as EquipmentItem).Equipment == Character.Equipment);
            Engine.GuiManager.OnScreenDrop += (what =>
            {
                EquipmentItem drop = what.UserData as EquipmentItem;
                drop.Equipment.RemoveItem(drop.Item);
                Described ob = drop.Item.CreateGameObject();
                ob.Position = Character.Position + Character.Orientation * Vector3.UNIT_Z;
            });
        }

        private void CreateMessageFrame()
        {
            MessageFrame = Engine.GuiManager.NewLayer("MessageFrame");
            MessageFrame.ZOrder = 1;
            MessageFrame.IsZOrderFixed = true;

            MessageFrame.SetControl(new GuiList("MessageList"));
            MessageList = MessageFrame.Control as GuiList;
            MessageList.Left = 0.05f * Engine.GuiManager.Proportions;
            MessageList.Top = 0.5f;
            MessageList.Width = 0.5f;
            MessageList.Height = 0.4f;
            MessageList.OnClick += (sender => true);
            MessageList.OnDropAccept += ((sender, what) => false);
            MessageList.IsVisible = true;

            ScreenMessages = new List<ScreenMessage>();
        }

        static int MsgLabelCnt = 0;
        public void PostScreenMessage(string text, float charheight = 0.035f)
        {
            GuiTextLabel msgLabel = new GuiTextLabel("MessageLabel" + MsgLabelCnt.ToString());
            msgLabel.Top = 0;
            msgLabel.Left = 0;
            msgLabel.Width = 0.3f;
            msgLabel.Height = charheight * 1.3f;
            msgLabel.FontName = "Ubuntu";
            msgLabel.CharHeight = charheight;
            msgLabel.ColourTop = new ColourValue(0.3f, 0.1f, 0);
            msgLabel.ColourBottom = new ColourValue(1, 1.0f, 0.6f);
            msgLabel.Caption = text;
            msgLabel.IsVisible = true;
            MessageList.PlugItem(msgLabel);
            msgLabel.UserData = new ScreenMessage(msgLabel, 8);
            ScreenMessages.Add(msgLabel.UserData as ScreenMessage);

            if (MessageList.Items.Count > MessageList.Items.Count(item => item.IsVisible))
                MessageList.ScrollPosition++;

            MsgLabelCnt++;
        }

        public void UpdateScreenMessages()
        {
            ScreenMessages.ForEach(msg =>
            {
                msg.Update();
                if (msg.IsOutDated)
                {
                    MessageList.UnplugItem(msg.Control);
                    msg.Control.Destroy();
                }
            });
            ScreenMessages.RemoveAll(msg => msg.IsOutDated);
        }

        private void CreateLifeBarsFrame()
        {
            LifeBarsFrame = Engine.GuiManager.NewLayer("LifeBarsFrame");
            LifeBarsFrame.ZOrder = 1;
            LifeBarsFrame.IsZOrderFixed = true;
            LifeBarsFrame.SetControl(new GuiControl("LifeBarsPanel"));
            LifeBarsFrame.Control.Left = 0;
            LifeBarsFrame.Control.Top = 0;
            LifeBarsFrame.Control.Width = 1;
            LifeBarsFrame.Control.Height = 1;
            LifeBarsFrame.Control.IsVisible = false;

            LifeBarPlayerBg = new GuiControl("LifeBarPlayerBg");
            LifeBarPlayerBg.AttachTo(LifeBarsFrame.Control);
            LifeBarPlayerBg.Left = 0.05f;
            LifeBarPlayerBg.Top = 0.94f;
            LifeBarPlayerBg.Width = LifeBarWidth;
            LifeBarPlayerBg.Height = 0.02f;
            LifeBarPlayerBg.MaterialName = "Overlay/LifeBarBg";

            LifeBarPlayer = new GuiControl("LifeBarPlayer");
            LifeBarPlayer.AttachTo(LifeBarPlayerBg);
            LifeBarPlayer.Left = 0;
            LifeBarPlayer.Top = 0;
            LifeBarPlayer.Width = LifeBarWidth;
            LifeBarPlayer.Height = 0.02f;
            LifeBarPlayer.MaterialName = "Overlay/LifeBar";

            LifeBarNPCBg = new GuiControl("LifeBarNPCBg");
            LifeBarNPCBg.AttachTo(LifeBarsFrame.Control);
            LifeBarNPCBg.Left = 0.4f;
            LifeBarNPCBg.Top = 0.05f;
            LifeBarNPCBg.Width = LifeBarWidth;
            LifeBarNPCBg.Height = 0.02f;
            LifeBarNPCBg.MaterialName = "Overlay/LifeBarBg";
            LifeBarNPCBg.IsVisible = false;

            LifeBarNPC = new GuiControl("LifeBarNPC");
            LifeBarNPC.AttachTo(LifeBarNPCBg);
            LifeBarNPC.Left = 0;
            LifeBarNPC.Top = 0;
            LifeBarNPC.Width = LifeBarWidth;
            LifeBarNPC.Height = 0.02f;
            LifeBarNPC.MaterialName = "Overlay/LifeBar";

            Crosshair = new GuiControl("Crosshair");
            Crosshair.AttachTo(LifeBarsFrame.Control);
            Crosshair.Left = 0.5f - 0.025f / Engine.Camera.AspectRatio;
            Crosshair.Top = 0.5f- 0.025f;
            Crosshair.Width = 0.05f / Engine.Camera.AspectRatio;
            Crosshair.Height = 0.05f;
            Crosshair.MaterialName = "Overlay/Crosshair";
        }

        private void CreateGameEndFrame()
        {
            GameEndFrame = Engine.GuiManager.NewLayer("GameEndFrame");
            GameEndFrame.SetControl(new GuiControl("GameEndPanel"));
            GameEndFrame.Control.Top = 0.0f;
            GameEndFrame.Control.Left = 0.0f;
            GameEndFrame.Control.Width = 1;
            GameEndFrame.Control.Height = 1;
            GameEndFrame.Control.MaterialName = "Overlay/EndSplash";
            GameEndFrame.Control.IsVisible = false;
        }

        private void CreatePlunderFrame()
        {
            //PlunderFrame
            PlunderFrame = Engine.GuiManager.NewLayer("PlunderFrame");
            PlunderFrame.SetControl(new GuiControl("PlunderPanel"));
            PlunderFrame.Control.Top = 0.1f;
            PlunderFrame.Control.Left = 0.1f;
            PlunderFrame.Control.Width = 0.12f * Engine.GuiManager.Proportions;
            PlunderFrame.Control.Height = 0.7f;
            PlunderFrame.Control.MaterialName = "Overlay/Quad";
            PlunderFrame.Control.OnMouseRightPress += (control =>
            {
                ClearItemDescription(InventoryDescription, InventoryStats);
                return true;
            });
            //PlunderList
            PlunderList = new GuiList("PlunderList");
            PlunderList.AttachTo(PlunderFrame.Control);
            PlunderList.Left = 0.01f * Engine.GuiManager.Proportions;
            PlunderList.Top = 0.01f;
            PlunderList.Width = 0.101f * Engine.GuiManager.Proportions;
            PlunderList.Height = 0.68f;
            PlunderList.MaterialName = "Overlay/TalkQuad";
            PlunderList.OnDropAccept += ((list, what) =>
            {
                if (what.UserData is EquipmentItem)
                {
                    EquipmentItem drop = what.UserData as EquipmentItem;
                    if (drop.Equipment == Character.Equipment)
                        return ExchangeObject.Equipment.CanReceive(drop.Item);
                    else
                        return true;
                }
                return false;
            });

            PlunderList.OnDrop += ((list, what) =>
            {
                (list as GuiList).PlugItem(what);
                EquipmentItem drop = what.UserData as EquipmentItem;
                if (drop.Equipment == Character.Equipment)
                {
                    Character.Equipment.RemoveItem(drop.Item);
                    ExchangeObject.Equipment.AddItem(drop.Item);
                    drop.Equipment = ExchangeObject.Equipment;
                }
            });

            PlunderFrame.Control.IsVisible = false;
        }

        private void CreateTalkFrame()
        {
            SubtitlesFrame = Engine.GuiManager.NewLayer("SubtitlesFrame");
            SubtitlesFrame.SetControl(new GuiControl("SubtitlesPanel"));
            SubtitlesFrame.Control.Left = 0.05f;
            SubtitlesFrame.Control.Top = 0.05f;
            SubtitlesFrame.Control.Width = 0.9f;
            SubtitlesFrame.Control.Height = 0.2f;
            SubtitlesFrame.Control.MaterialName = "Overlay/TalkQuad";

            SubtitlesLabel = new GuiTextLabel("SubtitlesLable");
            SubtitlesLabel.AttachTo(SubtitlesFrame.Control);
            SubtitlesLabel.FontName = "Ubuntu";
            SubtitlesLabel.CharHeight = 0.027f;
            SubtitlesLabel.ColourTop = new ColourValue(0.7f, 0.4f, 0);
            SubtitlesLabel.ColourBottom = new ColourValue(1, 1, 0.6f);
            SubtitlesLabel.Alignment = TextAreaOverlayElement.Alignment.Center;
            SubtitlesLabel.Left = 0;
            SubtitlesLabel.Top = 0;
            SubtitlesLabel.Width = 0.9f;
            SubtitlesLabel.Height = 0.2f;

            RepliesFrame = Engine.GuiManager.NewLayer("TalkRepliesFrame");
            RepliesFrame.SetControl(new GuiControl("RepliesPanel"));
            RepliesFrame.Control.Left = 0;
            RepliesFrame.Control.Top = 0.7f;
            RepliesFrame.Control.Width = 1;
            RepliesFrame.Control.Height = 0.3f;
            RepliesFrame.Control.MaterialName = "Overlay/TalkQuad";

            RepliesList = new GuiList("RepliesList");
            RepliesList.AttachTo(RepliesFrame.Control);
            RepliesList.Left = 0.01f;
            RepliesList.Top = 0.01f;
            RepliesList.Width = 0.98f;
            RepliesList.Height = 0.28f;
            RepliesList.MaterialName = "Overlay/TalkQuad";

            RepliesFrame.Control.IsVisible = false;
            SubtitlesFrame.Control.IsVisible = false;
        }

        private void CreateInventoryFrame()
        {
            InventoryFrame = Engine.GuiManager.NewLayer("InventoryFrame");
            InventoryFrame.SetControl(new GuiControl("InventoryPanel"));
            InventoryFrame.Control.Top = 0.1f;
            InventoryFrame.Control.Left = 0.4f;
            InventoryFrame.Control.Width = 0.5f * Engine.GuiManager.Proportions;
            InventoryFrame.Control.Height = 0.7f;
            InventoryFrame.Control.MaterialName = "Overlay/HudInventory";
            InventoryFrame.Control.OnMouseRightPress += (control =>
            {
                ClearItemDescription(InventoryDescription, InventoryStats);
                return true;
            });
            //InventoryList
            InventoryList = new GuiList("InventoryList");
            InventoryList.AttachTo(InventoryFrame.Control);
            InventoryList.Left = 0.015f * Engine.GuiManager.Proportions;
            InventoryList.Top = 0.08f;
            InventoryList.Width = 0.101f * Engine.GuiManager.Proportions;
            InventoryList.Height = 0.68f;
            //InventoryList.MaterialName = "Overlay/TalkQuad";
            InventoryList.OnDropAccept += ((list, what) =>
            {
                if (what.UserData is EquipmentItem)
                {
                    EquipmentItem drop = what.UserData as EquipmentItem;
                    if (drop.Equipment != Character.Equipment)
                        return Character.Equipment.CanReceive(drop.Item);
                    else
                        return true;
                }
                return false;
            });
            InventoryList.OnDrop += ((list, what) =>
            {
                (list as GuiList).PlugItem(what);
                EquipmentItem drop = what.UserData as EquipmentItem;
                if (drop.Equipment != Character.Equipment)
                {
                    ExchangeObject.Equipment.RemoveItem(drop.Item);
                    Character.AddItem(drop.Item);
                    drop.Equipment = Character.Equipment;
                }
            });
            //InventoryDescription
            InventoryDescription = new GuiTextLabel("InventoryDescription");
            InventoryDescription.AttachTo(InventoryFrame.Control);
            InventoryDescription.Left = 0.13f * Engine.GuiManager.Proportions;
            InventoryDescription.Top = 0.01f;
            InventoryDescription.Width = 0.36f * Engine.GuiManager.Proportions;
            InventoryDescription.Height = 0.35f;
            InventoryDescription.Padding = 0.01f;
            //InventoryDescription.MaterialName = "Overlay/TalkQuad";
            InventoryDescription.FontName = "Ubuntu";
            InventoryDescription.CharHeight = 0.027f;
            InventoryDescription.ColourTop = new ColourValue(0.7f, 0.4f, 0);
            InventoryDescription.ColourBottom = new ColourValue(1, 1, 0.6f);
            InventoryDescription.TextWrap = true;
            InventoryDescription.Alignment = TextAreaOverlayElement.Alignment.Left;
            //InventoryStats
            InventoryStats = new GuiTextLabel("InventoryStats");
            InventoryStats.AttachTo(InventoryFrame.Control);
            InventoryStats.Left = 0.13f * Engine.GuiManager.Proportions;
            InventoryStats.Top = 0.37f;
            InventoryStats.Width = 0.36f * Engine.GuiManager.Proportions;
            InventoryStats.Height = 0.10f;
            InventoryStats.Padding = 0.01f;
            //InventoryStats.MaterialName = "Overlay/TalkQuad";
            InventoryStats.FontName = "Ubuntu";
            InventoryStats.CharHeight = 0.027f;
            InventoryStats.ColourTop = new ColourValue(0.7f, 0.4f, 0);
            InventoryStats.ColourBottom = new ColourValue(1, 1, 0.6f);
            InventoryStats.TextWrap = true;
            InventoryStats.Alignment = TextAreaOverlayElement.Alignment.Left;

            InventoryWeaponPistol = new GuiControl("InventoryWeaponPistol");
            InventoryWeaponPistol.AttachTo(InventoryFrame.Control);
            InventoryWeaponPistol.Left = 0.13f * Engine.GuiManager.Proportions;
            InventoryWeaponPistol.Top = 0.48f;
            InventoryWeaponPistol.Width = 0.10f * Engine.GuiManager.Proportions;
            InventoryWeaponPistol.Height = 0.0888f;
            //InventoryWeaponPistol.MaterialName = "Overlay/TalkQuad";
            InventoryWeaponPistol.OnDropAccept += ((sender, what) =>
                what.UserData is EquipmentItem
                && Character.Pistol == null
                && (what.UserData as EquipmentItem).Item is ItemPistol
                && (what.UserData as EquipmentItem).Equipment == Character.Equipment);
            InventoryWeaponPistol.OnDrop += ((sender, what) =>
            {
                what.AttachTo(sender);
                what.Left = 0;
                what.Top = 0;
                what.OnDragBegin += OnPistolDragBegin;

                ItemPistol item = (what.UserData as EquipmentItem).Item as ItemPistol;
                Character.Pistol = item;
            });


            InventoryWeaponM1H = new GuiControl("InventoryWeaponM1H");
            InventoryWeaponM1H.AttachTo(InventoryFrame.Control);
            InventoryWeaponM1H.Left = 0.24f * Engine.GuiManager.Proportions;
            InventoryWeaponM1H.Top = 0.48f;
            InventoryWeaponM1H.Width = 0.10f * Engine.GuiManager.Proportions;
            InventoryWeaponM1H.Height = 0.0888f;
            //InventoryWeaponM1H.MaterialName = "Overlay/TalkQuad";
            InventoryWeaponM1H.OnDropAccept += ((sender, what) =>
                what.UserData is EquipmentItem
                && Character.M1HWeapon == null
                && (what.UserData as EquipmentItem).Item is ItemM1H
                && (what.UserData as EquipmentItem).Equipment == Character.Equipment);
            InventoryWeaponM1H.OnDrop += ((sender, what) =>
            {
                what.AttachTo(sender);
                what.Left = 0;
                what.Top = 0;
                what.OnDragBegin += OnM1HDragBegin;

                ItemM1H item = (what.UserData as EquipmentItem).Item as ItemM1H;
                Character.M1HWeapon = item;
            });

            InventoryArmour = new GuiControl("InventoryArmour");
            InventoryArmour.AttachTo(InventoryFrame.Control);
            InventoryArmour.Left = 0.13f * Engine.GuiManager.Proportions;
            InventoryArmour.Top = 0.58f;
            InventoryArmour.Width = 0.10f * Engine.GuiManager.Proportions;
            InventoryArmour.Height = 0.0888f;
            //InventoryWeaponPistol.MaterialName = "Overlay/TalkQuad";
            InventoryArmour.OnDropAccept += ((sender, what) =>
                what.UserData is EquipmentItem
                && Character.Armour == null
                && (what.UserData as EquipmentItem).Item is ItemArmour
                && (what.UserData as EquipmentItem).Equipment == Character.Equipment);
            InventoryArmour.OnDrop += ((sender, what) =>
            {
                what.AttachTo(sender);
                what.Left = 0;
                what.Top = 0;
                what.OnDragBegin += OnArmourDragBegin;

                ItemArmour item = (what.UserData as EquipmentItem).Item as ItemArmour;
                Character.Armour = item;
            });

            InventoryFrame.Control.IsVisible = false;
        }

        public void OnPistolDragBegin(GuiControl sender)
        {
            sender.OnDragBegin -= OnPistolDragBegin;
            sender.Detach();
            Character.Pistol = null;
        }

        public void OnM1HDragBegin(GuiControl sender)
        {
            sender.OnDragBegin -= OnM1HDragBegin;
            sender.Detach();
            Character.M1HWeapon = null;
        }

        public void OnArmourDragBegin(GuiControl sender)
        {
            sender.OnDragBegin -= OnArmourDragBegin;
            sender.Detach();
            Character.Armour = null;
        }

        private void CreateBarterFrame()
        {
            BarterFrame = Engine.GuiManager.NewLayer("BarterFrame");
            BarterFrame.SetControl(new GuiControl("BarterPanel"));
            BarterFrame.Control.Top = 0.08f;
            BarterFrame.Control.Left = 0.1f;
            BarterFrame.Control.Width = 0.82f * Engine.GuiManager.Proportions;
            BarterFrame.Control.Height = 0.7f;
            BarterFrame.Control.MaterialName = "Overlay/Quad";
            //BarterPlayerEquip
            BarterPlayerEquip = new GuiList("BarterPlayerEquip");
            BarterPlayerEquip.AttachTo(BarterFrame.Control);
            BarterPlayerEquip.Left = 0.01f * Engine.GuiManager.Proportions;
            BarterPlayerEquip.Top = 0.01f;
            BarterPlayerEquip.Width = 0.101f * Engine.GuiManager.Proportions;
            BarterPlayerEquip.Height = 0.68f;
            BarterPlayerEquip.MaterialName = "Overlay/TalkQuad";
            BarterPlayerEquip.OnDropAccept += ((list, what) =>
                what.UserData is EquipmentItem && (what.UserData as EquipmentItem).Equipment == Character.Equipment);
            BarterPlayerEquip.OnDrop += ((list, what) => (list as GuiList).PlugItem(what));
            //BarterPlayerOffer
            BarterPlayerOffer = new GuiList("BarterPlayerOffer");
            BarterPlayerOffer.AttachTo(BarterFrame.Control);
            BarterPlayerOffer.Left = 0.12f * Engine.GuiManager.Proportions;
            BarterPlayerOffer.Top = 0.01f;
            BarterPlayerOffer.Width = 0.101f * Engine.GuiManager.Proportions;
            BarterPlayerOffer.Height = 0.68f;
            BarterPlayerOffer.MaterialName = "Overlay/TalkQuad";
            BarterPlayerOffer.OnDropAccept += ((list, what) =>
                what.UserData is EquipmentItem && (what.UserData as EquipmentItem).Equipment == Character.Equipment);
            BarterPlayerOffer.OnDrop += ((list, what) => (list as GuiList).PlugItem(what));

            //BarterNPCEquip
            BarterNPCEquip = new GuiList("BarterNPCEquip");
            BarterNPCEquip.AttachTo(BarterFrame.Control);
            BarterNPCEquip.Left = 0.71f * Engine.GuiManager.Proportions;
            BarterNPCEquip.Top = 0.01f;
            BarterNPCEquip.Width = 0.101f * Engine.GuiManager.Proportions;
            BarterNPCEquip.Height = 0.68f;
            BarterNPCEquip.MaterialName = "Overlay/TalkQuad";
            BarterNPCEquip.OnDropAccept += ((list, what) =>
                what.UserData is EquipmentItem && (what.UserData as EquipmentItem).Equipment == ExchangeObject.Equipment);
            BarterNPCEquip.OnDrop += ((list, what) => (list as GuiList).PlugItem(what));
            //BarterNPCOffer
            BarterNPCOffer = new GuiList("BarterNPCOffer");
            BarterNPCOffer.AttachTo(BarterFrame.Control);
            BarterNPCOffer.Left = 0.60f * Engine.GuiManager.Proportions;
            BarterNPCOffer.Top = 0.01f;
            BarterNPCOffer.Width = 0.101f * Engine.GuiManager.Proportions;
            BarterNPCOffer.Height = 0.68f;
            BarterNPCOffer.MaterialName = "Overlay/TalkQuad";
            BarterNPCOffer.OnDropAccept += ((list, what) =>
                what.UserData is EquipmentItem && (what.UserData as EquipmentItem).Equipment == ExchangeObject.Equipment);
            BarterNPCOffer.OnDrop += ((list, what) => (list as GuiList).PlugItem(what));

            //BarterDescription
            BarterDescription = new GuiTextLabel("BarterDescription");
            BarterDescription.AttachTo(BarterFrame.Control);
            BarterDescription.Left = 0.23f * Engine.GuiManager.Proportions;
            BarterDescription.Top = 0.01f;
            BarterDescription.Width = 0.36f * Engine.GuiManager.Proportions;
            BarterDescription.Height = 0.35f;
            BarterDescription.MaterialName = "Overlay/TalkQuad";
            BarterDescription.FontName = "Ubuntu";
            BarterDescription.CharHeight = 0.027f;
            BarterDescription.ColourTop = new ColourValue(0.7f, 0.4f, 0);
            BarterDescription.ColourBottom = new ColourValue(1, 1, 0.6f);
            BarterDescription.TextWrap = true;
            BarterDescription.Alignment = TextAreaOverlayElement.Alignment.Left;
            //BarterStats
            BarterStats = new GuiTextLabel("BarterStats");
            BarterStats.AttachTo(BarterFrame.Control);
            BarterStats.Left = 0.23f * Engine.GuiManager.Proportions;
            BarterStats.Top = 0.37f;
            BarterStats.Width = 0.36f * Engine.GuiManager.Proportions;
            BarterStats.Height = 0.1f;
            BarterStats.MaterialName = "Overlay/TalkQuad";
            BarterStats.FontName = "Ubuntu";
            BarterStats.CharHeight = 0.027f;
            BarterStats.ColourTop = new ColourValue(0.7f, 0.4f, 0);
            BarterStats.ColourBottom = new ColourValue(1, 1, 0.6f);
            BarterStats.TextWrap = true;
            BarterStats.Alignment = TextAreaOverlayElement.Alignment.Left;
            //BarterAcceptBtn
            BarterAcceptBtn = new GuiButton("BarterAcceptBtn");
            BarterAcceptBtn.AttachTo(BarterFrame.Control);
            BarterAcceptBtn.Left = 0.23f * Engine.GuiManager.Proportions;
            BarterAcceptBtn.Top = 0.53f;
            BarterAcceptBtn.Width = 0.16f * Engine.GuiManager.Proportions;
            BarterAcceptBtn.Height = 0.1f;
            BarterAcceptBtn.MaterialName = "Overlay/TalkQuad";
            BarterAcceptBtn.FontName = "Ubuntu";
            BarterAcceptBtn.CharHeight = 0.035f;
            BarterAcceptBtn.ColourTop = new ColourValue(0.7f, 0.4f, 0);
            BarterAcceptBtn.ColourBottom = new ColourValue(1, 1, 0.6f);
            BarterAcceptBtn.Alignment = TextAreaOverlayElement.Alignment.Center;
            BarterAcceptBtn.Caption = "Oferuj";
            BarterAcceptBtn.MaterialName = "Overlay/TalkQuad";
            BarterAcceptBtn.MouseOverMaterial = "Overlay/LightQuad";
            BarterAcceptBtn.MouseDownMaterial = "Overlay/DarkQuad";
            BarterAcceptBtn.MouseOutMaterial = "Overlay/TalkQuad";
            BarterAcceptBtn.OnClick += OnBarterOffer;

            BarterFrame.Control.IsVisible = false;
        }

        public void ClearItemDescription(GuiTextLabel description, GuiTextLabel stats)
        {
            stats.Caption = "---";
            description.Caption = "---";
        }
   
        public bool OnBarterOffer(GuiControl sender)
        {
            float playerValue = 0;
            float playerWieght = 0;
            float npcValue = 0;
            float npcWeight = 0;
            foreach (GuiControl item in BarterPlayerOffer.Items)
            {
                playerValue += (item.UserData as EquipmentItem).Item.Value;
                playerWieght += (item.UserData as EquipmentItem).Item.Weight;
            }
            foreach (GuiControl item in BarterNPCOffer.Items)
            {
                npcValue += (item.UserData as EquipmentItem).Item.Value;
                npcWeight += (item.UserData as EquipmentItem).Item.Weight;
            }

            // IF Price is ok and everyone can lift his items
            if (playerValue >= npcValue
                && Character.Equipment.Weight - playerWieght + npcWeight <= Character.Equipment.Capacity
                && ExchangeObject.Equipment.Weight - npcWeight + playerWieght <= ExchangeObject.Equipment.Capacity)
            {
                // Put items on the "table"
                foreach (GuiControl item in BarterPlayerOffer.Items)
                    Character.Equipment.RemoveItem((item.UserData as EquipmentItem).Item);
                foreach (GuiControl item in BarterNPCOffer.Items)
                    ExchangeObject.Equipment.RemoveItem((item.UserData as EquipmentItem).Item);
                // Everyone picks his items
                foreach (GuiControl item in BarterPlayerOffer.Items)
                    ExchangeObject.Equipment.AddItem((item.UserData as EquipmentItem).Item);
                foreach (GuiControl item in BarterNPCOffer.Items)
                    Character.Equipment.AddItem((item.UserData as EquipmentItem).Item);

                // Redraw elements
                ClearBarterLists();
                FillBarterLists();
            }
            return false;
        }
   
             

        public void FillRepliesList(TalkReaction node)
        {
            RepliesList.ClearItems();

            foreach (TalkReply reply in node.Replies)
            {
                if (reply.IsConditionFulfilled())
                {
                    GuiButton replyLabel = new GuiButton("Reply" + reply.GetHashCode());
                    replyLabel.Width = 0.97f;
                    replyLabel.Height = 0.035f;
                    replyLabel.FontName = "Ubuntu";
                    replyLabel.CharHeight = 0.027f;
                    replyLabel.ColourTop = new ColourValue(0.7f, 0.4f, 0);
                    replyLabel.ColourBottom = new ColourValue(1, 1, 0.6f);
                    int newLineChar = reply.Text[0].Text.IndexOf('\n');                  
                    replyLabel.Caption = (newLineChar != -1 ? reply.Text[0].Text.Substring(0, newLineChar) : reply.Text[0].Text);
                    replyLabel.Alignment = TextAreaOverlayElement.Alignment.Left;
                    replyLabel.Padding = 0.005f;
                    replyLabel.MaterialName = "Overlay/Blank";
                    replyLabel.MouseDownMaterial = "Overlay/LightQuad";
                    replyLabel.MouseOutMaterial = "Overlay/Blank";
                    replyLabel.MouseOverMaterial = "Overlay/DarkQuad";
                    replyLabel.UserData = reply;
                    replyLabel.OnClick += Engine.HumanController.OnReplyClick;

                    RepliesList.PlugItem(replyLabel);
                }
            }

            Engine.GuiManager.MoveLayerToTop(RepliesFrame);
        }
        
        public void FillInventoryList()
        {
            FillEquipmentList(InventoryList, Character.Equipment, InventoryDescription, InventoryStats);
            FillWeapons();
        }

        public void ClearInventoryList()
        {
            InventoryList.ClearItems();
            InventoryWeaponPistol.DestroyAllChildren();
            InventoryWeaponM1H.DestroyAllChildren();
            InventoryArmour.DestroyAllChildren();
        }

        public void FillPlunderList()
        {
            FillEquipmentList(InventoryList, Character.Equipment, InventoryDescription, InventoryStats);
            FillEquipmentList(PlunderList, ExchangeObject.Equipment, InventoryDescription, InventoryStats);
        }
        public void ClearPlunderList()
        {
            ClearInventoryList();
            PlunderList.ClearItems();
        }
        public void FillBarterLists()
        {
            FillEquipmentList(BarterPlayerEquip, Character.Equipment, BarterDescription, BarterStats);
            FillEquipmentList(BarterNPCEquip, ExchangeObject.Equipment, BarterDescription, BarterStats);
        }
        public void ClearBarterLists()
        {
            BarterPlayerEquip.ClearItems();
            BarterPlayerOffer.ClearItems();
            BarterNPCEquip.ClearItems();
            BarterNPCOffer.ClearItems();
        }

        public void FillWeapons()
        {
            if (Character.Pistol != null)
            {
                GuiControl control = CreateItemControl(Character.Equipment, InventoryDescription, InventoryStats, Character.Pistol);
                control.OnDragBegin += OnPistolDragBegin;
                control.AttachTo(InventoryWeaponPistol);
            }
            if (Character.M1HWeapon != null)
            {
                GuiControl control = CreateItemControl(Character.Equipment, InventoryDescription, InventoryStats, Character.M1HWeapon);
                control.OnDragBegin += OnM1HDragBegin;
                control.AttachTo(InventoryWeaponM1H);
            }
            if (Character.Armour != null)
            {
                GuiControl control = CreateItemControl(Character.Equipment, InventoryDescription, InventoryStats, Character.Armour);
                control.OnDragBegin += OnArmourDragBegin;
                control.AttachTo(InventoryArmour);
            }
        }

        public void FillEquipmentList(GuiList list, Equipment equipment, GuiTextLabel description, GuiTextLabel stats)
        {
            list.ClearItems();
            foreach (Item item in equipment.Items)
            {
                // If item is being dragged we need to avoid duplicating it
                if (Engine.GuiManager.DragControl != null && Engine.GuiManager.DragControl.Name == "EquipmentItem" + item.SerialId)
                    continue;
                if (item.IsWorn)
                    continue;

                GuiControl itemControl = CreateItemControl(equipment, description, stats, item);
                list.PlugItem(itemControl);
            }
            list.Update();
        }

        public GuiControl CreateItemControl(Equipment equipment, GuiTextLabel description, GuiTextLabel stats, Item item)
        {
            GuiControl itemControl = new GuiControl("EquipmentItem" + item.SerialId);
            itemControl.Width = 0.10f * Engine.GuiManager.Proportions;
            itemControl.Height = 0.0888f;
            itemControl.MaterialName = item.SpriteMaterial;
            itemControl.IsDraggable = true;
            itemControl.UserData = new EquipmentItem(item, equipment);
            itemControl.OnMouseRightPress += (sender =>
            {
                EquipmentItem eqitem = sender.UserData as EquipmentItem;
                DisplayItemDescription(eqitem.Item, description, stats);
                return false;
            });
            return itemControl;
        }



        public void DisplayItemDescription(Item item, GuiTextLabel description, GuiTextLabel stats)
        {
            description.Caption = item.Profile.Description;
            stats.Caption =
                "Waga: " + item.Weight.ToString() + ". Cena: " + item.Value.ToString() + "\n" +
                "Id: " + item.SerialId;
        }                         

        void UpdateLifeBar(GuiControl control, Character character)
        {
            LifeBarPlayerBg.IsVisible = true;
            float healthRatio = (character.Profile.Stats.CurrentHP / character.Profile.Stats.MaxHP);
            control.Width = LifeBarWidth * healthRatio;
            control.Panel.SetParameter("uv_coords", "0 0 " + healthRatio.ToString(CultureInfo.InvariantCulture) + " 1");
        }

        void UpdateNPCLifeBar()
        {
            LifeBarNPCBg.IsVisible = FocusObject != null && FocusObject is Character;
            if (FocusObject is Character)
                UpdateLifeBar(LifeBarNPC, FocusObject as Character);
        }

        public void Update()
        {
            if (Character != null)
            {
                UpdateLifeBar(LifeBarPlayer, Character);
                UpdateNPCLifeBar();
                UpdateScreenMessages();
            }
            else
            {
                FocusLabel.IsVisible = false;
                LifeBarNPCBg.IsVisible = false;
                LifeBarPlayerBg.IsVisible = false;
            }
        }
    }
}
